import axios, {type AxiosInstance, type AxiosResponse} from 'axios'
import type {Result} from '@/types/common'
import {TOKEN_KEY} from '@/constants/app'

const http: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE || '/api',
    timeout: 15000,
})

// 请求拦截器
http.interceptors.request.use((config) => {
    const token = localStorage.getItem(TOKEN_KEY)
    if (token) {
        config.headers = config.headers || {}
        config.headers['Authorization'] = `Bearer ${token}`
    }

    // FormData 请求不设置 Content-Type
    if (config.data instanceof FormData && config.headers) {
        delete config.headers['Content-Type']
    }

    return config
}, (error) => {
    return Promise.reject(error)
})

// 响应拦截器
http.interceptors.response.use(
    (response: AxiosResponse<Result<any>>) => {
        const res = response.data

        if (res && typeof res.code === 'number') {
            if (res.code === 20000) {
                return res.data
            } else {
                return Promise.reject(new Error(res.message || `请求失败 (${res.code})`))
            }
        }

        return Promise.reject(new Error('响应格式错误'))
    },
    (error) => {
        let message = '网络错误，请稍后重试'

        if (error?.response) {
            const {status, data} = error.response

            switch (status) {
                case 400:
                    message = data?.message || '请求参数错误'
                    break
                case 401:
                    message = '登录已过期，请重新登录'
                    localStorage.removeItem(TOKEN_KEY)
                    if (window.location.pathname !== '/login') {
                        setTimeout(() => {
                            window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname)
                        }, 1000)
                    }
                    break
                case 403:
                    message = data?.message || '没有权限访问'
                    break
                case 404:
                    message = data?.message || '请求的资源不存在'
                    break
                case 500:
                    message = data?.message || '服务器内部错误'
                    break
                default:
                    message = data?.message || error?.message || '网络错误'
            }
        } else if (error?.message === 'Network Error') {
            message = '网络连接失败，请检查网络设置'
        }

        return Promise.reject(new Error(message))
    }
)

const request = {
    get: <T = any>(url: string, config?: any): Promise<T> => {
        return http.get(url, config)
    },

    post: <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        return http.post(url, data, config)
    },

    put: <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        return http.put(url, data, config)
    },

    patch: <T = any>(url: string, data?: any, config?: any): Promise<T> => {
        return http.patch(url, data, config)
    },

    delete: <T = any>(url: string, config?: any): Promise<T> => {
        return http.delete(url, config)
    }
}

export default request

